/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.rbac.controller.company;

import com.alibaba.fastjson2.JSONArray;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.je.common.base.DynaBean;
import com.je.common.base.controller.CommonTreeController;
import com.je.common.base.exception.PlatformException;
import com.je.common.base.exception.PlatformExceptionEnum;
import com.je.common.base.mvc.BaseMethodArgument;
import com.je.common.base.result.BaseRespResult;
import com.je.common.base.result.DirectJsonResult;
import com.je.common.base.service.CommonTreeService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.service.rpc.SystemSettingRpcService;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.ibatis.extension.plugins.pagination.Page;
import com.je.rbac.annotation.ControllerAuditLog;
import com.je.rbac.exception.AccountException;
import com.je.rbac.exception.DepartmentUserException;
import com.je.rbac.service.company.RbacDepartmentService;
import com.je.rbac.service.company.RbacDepartmentUserService;
import com.je.rbac.service.company.userCheckFilter.Response;
import com.je.rbac.service.company.userCheckFilter.UserFilterChainPattern;
import com.je.rbac.service.remove.CompanyDeptMoveService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/je/rbac/cloud/deptuser")
public class RbacDepartmentUserController extends CommonTreeController {

    @Autowired
    private RbacDepartmentUserService rbacDepartmentUserService;
    @Autowired
    private RbacDepartmentService rbacDepartmentService;
    @Autowired
    private CommonTreeService commonTreeService;
    @Autowired
    private SystemSettingRpcService systemSettingRpcService;
    @Autowired
    private CompanyDeptMoveService companyDeptMoveService;
    @Autowired
    private BeanService beanService;
    @Autowired
    private UserFilterChainPattern userFilterChainPattern;

    /***
     * 加载员工列表
     * @param param
     * @param request
     * @return
     */
    @Override
    @RequestMapping(value = {"/load"}, method = {RequestMethod.POST}, produces = {"application/json; charset=utf-8"})
    @ControllerAuditLog(moduleName = "部门管理", operateTypeCode = "loadDepartmentUser", operateTypeName = "加载部门人员", logTypeCode = "systemManage", logTypeName = "系统管理")
    public BaseRespResult load(BaseMethodArgument param, HttpServletRequest request) {
        rbacDepartmentUserService.loadParam(param);
        Page page = this.manager.load(param, request);
        return page == null ? BaseRespResult.successResultPage(Lists.newArrayList(), 0L) : BaseRespResult.successResultPage(page.getRecords(), (long) page.getTotal());
    }

    @RequestMapping(value = {"/getUserInfoByIdAndDepartmentId"}, method = {RequestMethod.POST}, produces = {"application/json; charset=utf-8"})
    public BaseRespResult getUserInfoByIdAndDeptId(BaseMethodArgument param, HttpServletRequest request) {
        String departmentId = getStringParameter(request, "departmentId");
        String userId = getStringParameter(request, "userId");
        DynaBean infoById = this.metaService.selectOne("JE_RBAC_VDEPTUSER", ConditionsWrapper.builder()
                .eq("JE_RBAC_DEPARTMENT_ID", departmentId)
                .eq("JE_RBAC_USER_ID", userId));
        if (infoById == null) {
            return BaseRespResult.successResult(new HashMap());
        } else {
            HashMap<String, Object> values = infoById.getValues();
            return BaseRespResult.successResult(values);
        }
    }

    /***
     * 保存
     * @param param
     * @param request
     * @return
     */
    @Override
    @RequestMapping(value = {"/doSave"}, method = {RequestMethod.POST}, produces = {"application/json; charset=utf-8"})
    @ControllerAuditLog(moduleName = "部门管理", operateTypeCode = "saveDepartmentUser", operateTypeName = "保存部门人员", logTypeCode = "systemManage", logTypeName = "系统管理")
    public BaseRespResult doSave(BaseMethodArgument param, HttpServletRequest request) {
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        if (dynaBean == null) {
            return BaseRespResult.errorResult("请设置相关参数！");
        }
        //用户信息唯一校验
        Response response = Response.build().setSuccess(true).setMessage("");
        userFilterChainPattern.exec(request, response);
        if (!response.isSuccess()) {
            return BaseRespResult.errorResult(response.getMessage());
        }
        DynaBean savedBean = rbacDepartmentUserService.doSave(dynaBean);
        JSONTreeNode node = commonTreeService.buildSingleTreeNode(savedBean);
        Map<String, Object> result = new HashMap<>();
        result.put("dynaBean", savedBean.getValues());
        result.put("node", node);
        return BaseRespResult.successResult(result);
    }

    /***
     * 修改
     * @param param
     * @param request
     * @return
     */
    @Override
    @RequestMapping(value = {"/doUpdate"}, method = {RequestMethod.POST}, produces = {"application/json; charset=utf-8"})
    @ControllerAuditLog(moduleName = "部门管理", operateTypeCode = "updateDepartmentUser", operateTypeName = "更新部门人员", logTypeCode = "systemManage", logTypeName = "系统管理")
    public BaseRespResult doUpdate(BaseMethodArgument param, HttpServletRequest request) {
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        if (dynaBean == null) {
            return BaseRespResult.errorResult("请设置相关参数！");
        }
        //用户信息唯一校验
        Response response = Response.build().setSuccess(true).setMessage("");
        userFilterChainPattern.exec(request, response);
        if (!response.isSuccess()) {
            return BaseRespResult.errorResult(response.getMessage());
        }
        DynaBean updatedBean = rbacDepartmentUserService.doUpdate(dynaBean);
        JSONTreeNode node = commonTreeService.buildSingleTreeNode(updatedBean);
        Map<String, Object> result = new HashMap<>();
        result.put("dynaBean", updatedBean.getValues());
        result.put("node", node);
        return BaseRespResult.successResult(result);
    }

    /***
     * 列表修改
     * @param param
     * @param request
     * @return
     */
    @Override
    @RequestMapping(value = {"/doUpdateList"}, method = {RequestMethod.POST}, produces = {"application/json; charset=utf-8"})
    @ControllerAuditLog(moduleName = "部门管理", operateTypeCode = "updateDepartmentUserList", operateTypeName = "更新部门人员集合", logTypeCode = "systemManage", logTypeName = "系统管理")
    public BaseRespResult doUpdateList(BaseMethodArgument param, HttpServletRequest request) {
        List<Object> updateList = new ArrayList<>();
        List<JSONTreeNode> nodeList = new ArrayList<>();
        String strData = param.getStrData();
        String tableCode = param.getTableCode();
        List<DynaBean> lists = beanService.buildUpdateList(strData, tableCode);
        for (DynaBean bean : lists) {
            metaService.update(bean);
            DynaBean dynaBean = metaService.selectOneByPk(bean.getTableCode(), bean.getPkValue());
//            nodeList.add(commonTreeService.buildSingleTreeNode(dynaBean));
//            updateList.add(dynaBean.getValues());
        }
        Map<String, Object> result = new HashMap<>();
        result.put("dynaBeans", updateList);
        result.put("nodes", nodeList);
        return BaseRespResult.successResult(result, String.format("%s 条记录被更新", lists.size()));
    }

    @RequestMapping(
            value = {"/remove"},
            method = {RequestMethod.POST},
            produces = {"application/json; charset=utf-8"}
    )
    @ControllerAuditLog(moduleName = "部门管理", operateTypeCode = "removeDepartmentUser", operateTypeName = "移除部门人员", logTypeCode = "systemManage", logTypeName = "系统管理")
    public BaseRespResult remove(BaseMethodArgument param, HttpServletRequest request) {
        String userDeptIds = getStringParameter(request, "userDeptIds");
        if (Strings.isNullOrEmpty(userDeptIds)) {
            return BaseRespResult.errorResult("请选择部门或人员！");
        }
        try {
            rbacDepartmentUserService.doUserRemove(userDeptIds);
        } catch (AccountException e) {
            return BaseRespResult.errorResult(e.getMessage());
        }
        return BaseRespResult.successResult("操作成功！");
    }

    @RequestMapping(
            value = {"/getTree"},
            method = {RequestMethod.POST},
            produces = {"application/json; charset=utf-8"}
    )
    @Override
    public BaseRespResult getTree(BaseMethodArgument param, HttpServletRequest request) {
        try {
            JSONTreeNode tree = rbacDepartmentService.buildCompanyTreeData(true);
            return tree != null ? BaseRespResult.successResult(DirectJsonResult.buildObjectResult(tree)) : BaseRespResult.successResult(DirectJsonResult.buildObjectResult("{}"));
        } catch (PlatformException var4) {
            throw var4;
        } catch (Exception var5) {
            throw new PlatformException("数据加载失败！", PlatformExceptionEnum.UNKOWN_ERROR, var5);
        }
    }

    /**
     * 变更部门
     *
     * @param request
     * @return
     */
    @RequestMapping(value = {"/changeDepartment"}, method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    @ControllerAuditLog(moduleName = "部门管理", operateTypeCode = "changeUserDepartment", operateTypeName = "变更人员部门", logTypeCode = "systemManage", logTypeName = "系统管理")
    public BaseRespResult changeDepartment(HttpServletRequest request) {
        String userDeptIds = getStringParameter(request, "userDeptIds");
        if (Strings.isNullOrEmpty(userDeptIds)) {
            return BaseRespResult.errorResult("请选择部门或人员！");
        }
        try {
            rbacDepartmentUserService.changeDepartment(userDeptIds);
        } catch (Exception e) {
            return BaseRespResult.errorResult(e.getMessage());
        }
        return BaseRespResult.successResult("操作成功！");
    }

    /**
     * 添加人员至其他部门（添加分属组织）
     *
     * @param request
     * @return
     */
    @RequestMapping(value = {"/addToOtherDepartment"}, method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    @ControllerAuditLog(moduleName = "部门管理", operateTypeCode = "addUserToOtherDepartment", operateTypeName = "添加人员至其他部门", logTypeCode = "systemManage", logTypeName = "系统管理")
    public BaseRespResult addToOtherDepartment(HttpServletRequest request) {
        String userDeptIds = getStringParameter(request, "userDeptIds");
        if (Strings.isNullOrEmpty(userDeptIds)) {
            return BaseRespResult.errorResult("请选择部门或人员！");
        }
        try {
            JSONArray array = JSONArray.parseArray(userDeptIds);
            for (int i = 0; i < array.size(); i++) {
                //分部门ID
                String departmentId = array.getJSONObject(i).getString("departmentId");
                //需判断该人员所属部门状态
                DynaBean department = rbacDepartmentService.findById(departmentId);
                if (department == null) {
                    return BaseRespResult.errorResult("当前部门不存在！");
                }
                rbacDepartmentUserService.addOtherDepartment(userDeptIds);
            }
        } catch (DepartmentUserException e) {
            return BaseRespResult.errorResult(e.getMessage());
        }
        return BaseRespResult.successResult("操作成功！");
    }

    /**
     * 允许访问系统
     *
     * @param request
     * @return
     */
    @RequestMapping(value = {"/openAccount"}, method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    @ControllerAuditLog(moduleName = "部门管理", operateTypeCode = "openAccountDepartmentUser", operateTypeName = "允许部门人员访问系统", logTypeCode = "systemManage", logTypeName = "系统管理")
    public BaseRespResult openAccount(HttpServletRequest request) {
        String userDeptIds = getStringParameter(request, "userDeptIds");
        if (Strings.isNullOrEmpty(userDeptIds)) {
            return BaseRespResult.errorResult("请选择部门或人员！");
        }
        try {
            rbacDepartmentUserService.openAccount(userDeptIds);
        } catch (AccountException e) {
            return BaseRespResult.errorResult(e.getMessage());
        }
        return BaseRespResult.successResult("操作成功!");
    }

    /**
     * 禁止访问系统-禁用该人员的账号
     *
     * @param request
     * @return
     */
    @RequestMapping(value = {"/disableUserAccount"}, method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    @ControllerAuditLog(moduleName = "部门管理", operateTypeCode = "disableAccountDepartmentUser", operateTypeName = "禁止部门人员访问系统", logTypeCode = "systemManage", logTypeName = "系统管理")
    public BaseRespResult disableUserAccount(HttpServletRequest request) {
        String userDeptIds = getStringParameter(request, "userDeptIds");
        if (Strings.isNullOrEmpty(userDeptIds)) {
            return BaseRespResult.errorResult("请选择部门或人员！");
        }
        try {
            rbacDepartmentUserService.disableUsers(userDeptIds);
        } catch (Exception e) {
            return BaseRespResult.errorResult(e.getMessage());
        }
        return BaseRespResult.successResult("操作成功！");
    }

    /**
     * 加载人员账号权限树
     *
     * @param request
     * @return
     */
    @RequestMapping(value = {"/loadAccountPermissionTree"}, method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult loadAccountPermissionTree(HttpServletRequest request) throws DepartmentUserException {
        String userIds = getStringParameter(request, "userIds");
        if (Strings.isNullOrEmpty(userIds)) {
            return BaseRespResult.errorResult("请选择人员！");
        }
        JSONTreeNode root = rbacDepartmentUserService.loadAccountPermissionTree(userIds);
        return BaseRespResult.successResult(root);
    }

    /**
     * 操作离职
     *
     * @param request
     * @return
     */
    @RequestMapping(value = {"/disableUser"}, method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    @ControllerAuditLog(moduleName = "部门管理", operateTypeCode = "disableDepartmentUser", operateTypeName = "禁止部门人员", logTypeCode = "systemManage", logTypeName = "系统管理")
    public BaseRespResult disableAccount(HttpServletRequest request) {
        String userIds = getStringParameter(request, "userIds");
        if (Strings.isNullOrEmpty(userIds)) {
            return BaseRespResult.errorResult("请选择人员！");
        }
        try {
            rbacDepartmentUserService.operationQuitJob(userIds);
        } catch (DepartmentUserException e) {
            return BaseRespResult.errorResult("操作失败！");
        }
        return BaseRespResult.successResult("操作成功！");
    }

    /**
     * 操作在职
     *
     * @param request
     * @return
     */
    @RequestMapping(value = {"/enableUser"}, method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    @ControllerAuditLog(moduleName = "部门管理", operateTypeCode = "enableDepartmentUser", operateTypeName = "启用部门人员", logTypeCode = "systemManage", logTypeName = "系统管理")
    public BaseRespResult enableAccount(HttpServletRequest request) {
        String userIds = getStringParameter(request, "userIds");
        if (Strings.isNullOrEmpty(userIds)) {
            return BaseRespResult.errorResult("请选择人员！");
        }
        try {
            rbacDepartmentUserService.operationOnTheJob(userIds);
        } catch (DepartmentUserException e) {
            return BaseRespResult.errorResult("操作失败！");
        }
        return BaseRespResult.successResult("操作成功！");
    }

    /**
     * 人员年龄计算
     *
     * @param request
     * @return
     */
    @RequestMapping(value = {"/userAgeCalculation"}, method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult userAgeCalculation(HttpServletRequest request) throws DepartmentUserException {
        try {
            rbacDepartmentUserService.userAgeCalculation();
        } catch (DepartmentUserException e) {
            return BaseRespResult.errorResult(e.getMessage());
        }
        return BaseRespResult.successResult("操作成功！");
    }


    /**
     * 重置密码
     *
     * @param request
     * @return
     */
    @RequestMapping(value = {"/userResetPassword"}, method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    @ControllerAuditLog(moduleName = "部门管理", operateTypeCode = "resetDepartmentUserPassword", operateTypeName = "重置部门人员密码", logTypeCode = "systemManage", logTypeName = "系统管理")
    public BaseRespResult userResetPassword(HttpServletRequest request) {
        String userIds = getStringParameter(request, "userIds");
        if (Strings.isNullOrEmpty(userIds)) {
            return BaseRespResult.errorResult("请选择人员！");
        }
        String defaultPassword = systemSettingRpcService.findSettingValue("JE_SYS_PASSWORD");
        if (Strings.isNullOrEmpty(defaultPassword)) {
            return BaseRespResult.errorResult("系统设置默认密码为空！");
        }
        try {
            rbacDepartmentUserService.userResetPassword(userIds);
        } catch (Exception e) {
            return BaseRespResult.errorResult("重置密码失败！" + e.getMessage());
        }

        return BaseRespResult.successResult("重置成功，密码为：" + defaultPassword);
    }


    /**
     * 解除锁定
     *
     * @param request
     * @return
     */
    @RequestMapping(value = {"/userUnlock"}, method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    @ControllerAuditLog(moduleName = "部门管理", operateTypeCode = "unlockDepartmentUser", operateTypeName = "解除部门人员锁定", logTypeCode = "systemManage", logTypeName = "系统管理")
    public BaseRespResult userUnlock(HttpServletRequest request) {
        String userIds = getStringParameter(request, "userIds");
        if (Strings.isNullOrEmpty(userIds)) {
            return BaseRespResult.errorResult("请选择要解除账号锁定的人员！");
        }
        try {
            rbacDepartmentUserService.userUnlock(userIds);
        } catch (PlatformException e) {
            BaseRespResult.errorResult(e.getMessage());
        }
        return BaseRespResult.successResult("操作成功！");
    }

    /**
     * 员工排序-获取公司组织人员树形
     *
     * @param request
     * @return
     */
    @RequestMapping(value = {"/getUserTree"}, method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult getUserTree(HttpServletRequest request) {
        try {
            JSONTreeNode tree = rbacDepartmentUserService.findOrgStructureAndBuildTreeNode();
            return tree != null ? BaseRespResult.successResult(DirectJsonResult.buildObjectResult(tree)) : BaseRespResult.successResult(DirectJsonResult.buildObjectResult("{}"));
        } catch (PlatformException var4) {
            throw var4;
        } catch (Exception var5) {
            throw new PlatformException("数据加载失败！", PlatformExceptionEnum.UNKOWN_ERROR, var5);
        }
    }

    @RequestMapping(value = {"/moveUserAndDept"}, method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public BaseRespResult moveUserAndDept(HttpServletRequest request) {
        String tableCode = getStringParameter(request, "tableCode");
        if (Strings.isNullOrEmpty(tableCode)) {
            return BaseRespResult.errorResult("请选择要移动数据的表编码！");
        }
        String id = getStringParameter(request, "id");
        if (Strings.isNullOrEmpty(id)) {
            return BaseRespResult.errorResult("请选择要移动数据的id！");
        }
        String toId = getStringParameter(request, "toId");
        if (Strings.isNullOrEmpty(toId)) {
            return BaseRespResult.errorResult("请选择要移动的目标数据id！");
        }
        String place = getStringParameter(request, "place");
        if (Strings.isNullOrEmpty(place)) {
            return BaseRespResult.errorResult("请选择要移动的数据位置！");
        }
        try {
            if (tableCode.equals("JE_RBAC_DEPTUSER")) {
                rbacDepartmentUserService.moveDeptUser(id, toId, place);
            } else {
                DynaBean dynaBean = new DynaBean(tableCode, false);
                dynaBean.put("id", id);
                dynaBean.put("toId", toId);
                dynaBean.put("place", place);
                companyDeptMoveService.move(dynaBean);
            }
        } catch (DepartmentUserException e) {
            return BaseRespResult.errorResult(e.getMessage());
        }

        return BaseRespResult.successResult("操作成功！");
    }

}
